package com.kanshu.basictest.sys;

import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.os.Process;
import android.util.Log;

import com.kanshu.basictest.BuildConfig;
import com.kanshu.basictest.MyApp;
import com.kanshu.basictest.util.TimeUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;

public class CrashHandler implements Thread.UncaughtExceptionHandler {

    private static final String TAG = "CrashHandler";

    private static final boolean DEBUG = false;
    //本地日志文件的存储路径
    private static final String LOG_FILE_PATH = Environment.getExternalStorageDirectory().getPath().concat("/AndroidBasicTest/log/");

    private static final String FILE_NAME_MAIN = "crash";
    private static final String FILE_NAME_SUFFIX = ".trace";


    private static CrashHandler sInstance = new CrashHandler();

    private Thread.UncaughtExceptionHandler mUncaughtExceptionHandler;

    private Context mContext;


    private CrashHandler() {
    }

    public static CrashHandler getInstance() {
        return sInstance;
    }

    public void init(Context context) {
        mUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
        mContext = context.getApplicationContext();
    }


    /**
     * 当程序出现未捕获异常时，系统会自动调用此方法
     *
     * @param t 出现未捕获异常的线程
     * @param e 异常信息
     */
    @Override
    public void uncaughtException(Thread t, Throwable e) {

        //将异常信息存储到文件
        dumpExceptionToSDCard(e);

        e.printStackTrace();
        //如果系统提供了默认的异常处理器，那么就交给默认的异常处理器去处理异常，
        //否则就杀死当前进程
        MyApp.closeAllActivity();
        if (mUncaughtExceptionHandler != null) {
            mUncaughtExceptionHandler.uncaughtException(t, e);
        } else {
            Process.killProcess(Process.myPid());
        }

    }


    /**
     * 将异常信息写到SD卡
     *
     * @param e 异常
     */
    private void dumpExceptionToSDCard(Throwable e) {

        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

            if (DEBUG) {
                Log.w(TAG, "当前设备尚未装载SD卡，无法写入异常文件！");
            }

            return;
        }

        File logDir = new File(LOG_FILE_PATH);

        if (!logDir.exists()) {
            logDir.mkdirs();
        }

        String time = TimeUtils.getCurrentTimeFormat("yyyy-MM-dd HH:mm:ss");

        File file = new File(LOG_FILE_PATH + FILE_NAME_MAIN + time + FILE_NAME_SUFFIX);

        try {
            PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));
            pw.println("##########" + time + "###########");
            dumpPhoneInfo(pw);
            pw.println();
            e.printStackTrace(pw);
            pw.close();
        } catch (IOException e1) {
            e1.printStackTrace();
            Log.w(TAG, "dumpExceptionToSDCard: e1", e1);
        }

    }


    private void dumpPhoneInfo(PrintWriter writer) {
        //应用版本
        writer.println("应用版本：" + BuildConfig.VERSION_NAME);

        //系统版本
        writer.println("系统版本: " + Build.VERSION.RELEASE + "_" + Build.VERSION.SDK_INT);

        //制造商
        writer.println("制造商：" + Build.MANUFACTURER);

        //设备型号
        writer.println("设备型号:" + Build.MODEL);

        //CPU结构
        writer.println("CPU架构:" + Arrays.toString(Build.SUPPORTED_ABIS));

    }


}
